//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//********************************************************* 

using System.Windows.Forms;
using Microsoft.TridentWordAddIn.Common;
using Microsoft.TridentWordAddIn.Server;

namespace Microsoft.TridentWordAddIn.Presentation
{
    /// <summary>
    /// Base class for Task Panes
    /// </summary>
    public class BaseUserControl : UserControl
    {
        /// <summary>
        /// disposed flag
        /// </summary>
        protected bool disposed;
        private int documentKey;
        private bool connectionAutoUpdate;
        private ITridentServer tridentserver;
        private IController controllerInstance;

        /// <summary>
        /// Gets or sets a value indicating whether this instance is connection update needed.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is connection update needed; otherwise, <c>false</c>.
        /// </value>
        protected bool IsConnectionUpdateNeeded { get; set; }

        /// <summary>
        /// Gets the document key.
        /// </summary>
        /// <value>The document key.</value>
        protected int DocumentKey
        {
            get { return this.documentKey; }
        }

        /// <summary>
        /// Gets the controller.
        /// </summary>
        /// <value>The controller.</value>
        protected IController ControllerInstance
        {
            get { return this.controllerInstance; }
        }

        /// <summary>
        /// Gets or sets the server.
        /// </summary>
        /// <value>The server.</value>
        protected ITridentServer Server
        {
            get
            {
                return this.tridentserver;
            }
            set
            {
                this.tridentserver = value;
            }
        }

        /// <summary>
        /// Gets a value indicating whether this instance is connection auto update.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is connection auto update; otherwise, <c>false</c>.
        /// </value>
        protected bool IsConnectionAutoUpdate
        {
            get
            {
                return this.connectionAutoUpdate;
            }
        }

        /// <summary>
        /// Initializes the specified auto update.
        /// </summary>
        /// <param name="autoUpdate">if set to <c>true</c> [auto update].</param>
         public virtual void Initialize(bool autoUpdate)
        {
            this.connectionAutoUpdate = autoUpdate;
            this.controllerInstance = Controller.Instance(null);
            this.documentKey = this.controllerInstance.CurrentDocumentKey;
            if (this.connectionAutoUpdate)
            {
                this.tridentserver = new TridentServer();
                this.tridentserver.CurrentTridentConnection = this.ControllerInstance.CurrentConnection;
            }

            this.controllerInstance.OnConnectionChanged += new System.EventHandler<ConnectionChangedEventArgs>(controllerInstance_OnConnectionChanged);
        }

        /// <summary>
        /// Handles the OnConnectionChanged event of the controllerInstance control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Microsoft.TridentWordAddIn.Common.ConnectionChangedEventArgs"/> instance containing the event data.</param>
        private void controllerInstance_OnConnectionChanged(object sender, ConnectionChangedEventArgs e)
        {
            if (this.connectionAutoUpdate)
            {
                this.OnConnectionChanged(e);
            }
        }

        /// <summary>
        /// Handles the OnConnectionChanged event of the Controller control.
        /// </summary>
        /// <param name="e">The <see cref="Microsoft.TridentWordAddIn.Common.ConnectionChangedEventArgs"/> instance containing the event data.</param>
        protected virtual void OnConnectionChanged(ConnectionChangedEventArgs e)
        {
            if (this.connectionAutoUpdate)
            {
                this.IsConnectionUpdateNeeded = false;
                if (e.DocumentKey == this.DocumentKey && e.Operation == ConnectionOperation.Changed)
                {
                    this.UpdateIfActiveDocument(e.Connection);
                }
                else if (this.Server.CurrentTridentConnection == null && e.Connection != null)
                {
                    this.UpdateIfConnectionIsNull(e.Connection);
                }
                else if (e.DocumentKey != this.DocumentKey)
                {
                    this.UpdateIfNotActiveDocument(e.Connection);
                }
            }
        }

        /// <summary>
        /// Updates if active document.
        /// </summary>
        /// <param name="connection">The connection.</param>
        private void UpdateIfActiveDocument(TridentConnection connection)
        {
            this.IsConnectionUpdateNeeded = true;
            this.Server.CurrentTridentConnection = connection;
        }

        /// <summary>
        /// Updates if connection is null.
        /// </summary>
        /// <param name="connection">The connection.</param>
        private void UpdateIfConnectionIsNull(TridentConnection connection)
        {
            this.IsConnectionUpdateNeeded = true;
            this.Server.CurrentTridentConnection = connection;
            this.ControllerInstance.SetConnectionByDocumentKey(this.documentKey, connection.Name);
        }

        /// <summary>
        /// Updates the connection of other documents.
        /// </summary>
        /// <param name="connection">The connection.</param>
        private void UpdateIfNotActiveDocument(TridentConnection connection)
        {
            if (connection == null)
            {
                this.IsConnectionUpdateNeeded = true;
            }
            else
            {
                string connectionName = this.ControllerInstance.GetConnectionByDocumentKey(this.DocumentKey);
                if (connectionName.IsNullOrEmpty())
                {
                    this.IsConnectionUpdateNeeded = true;
                    this.ControllerInstance.SetConnectionByDocumentKey(this.DocumentKey, connection.Name);
                }
                else if (connectionName.Compare(connection.Name) && !this.Server.CurrentTridentConnection.Equals(connection))
                {
                    this.IsConnectionUpdateNeeded = true;
                }
            }

            if (this.IsConnectionUpdateNeeded)
            {
                this.Server.CurrentTridentConnection = connection;
            }
        }

        /// <summary>
        /// Disposings this instance.
        /// </summary>
        protected new virtual void Disposing()
        {
            if (tridentserver != null)
            {
                tridentserver.Dispose();
            }
        }
    }
}
